package recycle;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CorsHandler;
import io.vertx.mysqlclient.MySQLPool;
import recycle.config.DatabaseConfig;
import recycle.config.VertxConfig;
import recycle.controller.AppointmentController;
import recycle.controller.CategoryController;
import recycle.controller.StationController;
import recycle.controller.UserController;
import recycle.handler.LoginInterceptor;
import recycle.repository.AppointmentRepository;
import recycle.repository.CategoryRepository;
import recycle.repository.StationRepository;
import recycle.repository.UserRepository;
import recycle.service.AppointmentService;
import recycle.service.CategoryService;
import recycle.service.StationService;
import recycle.service.UserService;

public class Application extends AbstractVerticle {


    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(new Application())
                .onSuccess(res -> System.out.println("Application deployed successfully"))
                .onFailure(err -> {
                    System.err.println("Failed to deploy application: " + err.getMessage());
                    err.printStackTrace();
                });
    }


    @Override
    public void start(Promise<Void> startPromise) {
        // 初始化数据库配置
        MySQLPool dbClient = DatabaseConfig.getMySQLPool(vertx);



        // 注册路由
        Router router = VertxConfig.initRouter(vertx);
        // 配置CorsHandler
        CorsHandler corsHandler = CorsHandler.create()
                .allowedMethod(io.vertx.core.http.HttpMethod.GET)
                .allowedMethod(io.vertx.core.http.HttpMethod.POST)
                .allowedMethod(io.vertx.core.http.HttpMethod.DELETE)
                .allowedMethod(io.vertx.core.http.HttpMethod.PUT)
                .allowedHeader("Content-Type")
                .allowedHeader("Authorization")
                .allowCredentials(true)
                .maxAgeSeconds(3600);

        // 将CorsHandler应用到所有路由
        router.route().handler(corsHandler);
        router.route().handler(ctx -> {
            ctx.response().putHeader("Content-Type", "application/json; charset=utf-8");
            ctx.next();
        });

        router.route().handler(new LoginInterceptor());
        router.route().handler(BodyHandler.create());




        // Repository
        UserRepository userRepository = new UserRepository(dbClient);
        CategoryRepository categoryRepository = new CategoryRepository(dbClient);
        StationRepository stationRepository = new StationRepository(dbClient);
        AppointmentRepository appointmentRepository = new AppointmentRepository(dbClient);


        // Service
        UserService userService = new UserService(userRepository);
        CategoryService categoryService = new CategoryService(categoryRepository);
        StationService stationService = new StationService(stationRepository);
        AppointmentService appointmentService = new AppointmentService(appointmentRepository,stationRepository,userRepository,categoryRepository);

        // Controller
        UserController userController = new UserController(userService);
        CategoryController categoryController = new CategoryController(categoryService);
        StationController stationController = new StationController(stationService);
        AppointmentController appointmentController = new AppointmentController(appointmentService);

        userController.setupRoutes(router);
        categoryController.setupRoutes(router);
        stationController.setupRoutes(router);
        appointmentController.setupRoutes(router);





        // 启动服务器
        vertx.createHttpServer()
                .requestHandler(router)
                .listen(8000)
                .onSuccess(server -> {
                    System.out.println("Server started on port 8000");
                    startPromise.complete();
                })
                .onFailure(startPromise::fail);
    }
}